/*******************************************************************************
 * Copyright (c) 2008 Jakub Kornas.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser Public License v2.1
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *     Jakub Kornas - initial API and implementation
 *     Sylvain Sicard - integration in FracLite Runtime
 ******************************************************************************/

package org.objectweb.fractal.deployment.local.api;

import java.util.HashMap;
import java.util.Map;

import org.objectweb.fractal.api.Component;
import org.objectweb.fractal.api.control.BindingController;
import org.objectweb.fractal.api.control.IllegalBindingException;

/**
 * Represents a locally installed {@link Component} package, its dependencies
 * and an associated {@link ILoader}. A {@link ModuleComponent} object is the
 * result of installing by an {@link IModuleComponentFactory} on a local machine
 * the resources obtained from the {@link IPhysicalPackageRepository} given a
 * {@link IModuleDescriptor}.
 * 
 * For garbage collection purpose each {@link ModuleComponent} needs to know how
 * many other {@link ModuleComponent}s depend on it (even though it does not
 * need to know who exactly depends on it). Therefore it maintains a reference
 * counter.
 * 
 * @author <a href="mailto:jakub.kornas@inrialpes.fr">Jakub Kornas
 */
public abstract class ModuleComponent implements BindingController,
		QueryInterface {

	protected Map<String, IPackageExport> importedSoftwarePackages = new HashMap<String, IPackageExport>();

	protected ClassLoader moduleClassLoader = null;

	/**
	 * Returns a {@link IModuleDescriptor} that corresponds to this
	 * {@link ModuleComponent}. Imports and exports of this
	 * {@link IModuleDescriptor} correspond to the imports/exports of this
	 * module component.
	 * 
	 * @return A {@link IModuleDescriptor} that corresponds to this
	 *         {@link ModuleComponent}
	 */
	public abstract IModuleDescriptor getPackageDescription();

	/**
	 * A marked {@link ModuleComponent} will never by garbage collected
	 * 
	 * @return true if this {@link ModuleComponent} is marked
	 */
	public abstract boolean isMarked();

	public void bindFc(String packageName, Object packageInterface)
			throws IllegalBindingException {
		if (!(packageInterface instanceof IPackageExport || packageInterface instanceof Component)) {
			throw new IllegalBindingException(
					"Module Components can only be bound to IPackageExport interfaces");
		} else if (packageInterface instanceof IPackageExport) {
			importedSoftwarePackages.put(packageName, (IPackageExport) packageInterface);
		}
	}

	public void unbindFc(String packageName) {
		importedSoftwarePackages.remove(packageName);
	}

}
